<template>
  <div class="bg-white">
    <div class="pos-rlt" :style="{ paddingLeft: `${fixedLeft ? fixedLeftWidth : 0}px` }">
      <div
        v-if="fixedLeft"
        class="pos-abs bg-white"
        :style="{
          boxSizing: `border-box`,
          width: `${fixedLeftWidth}px`,
          top: '0',
          left: '0',
          borderRight: 'solid 1px #e6e6e6',
          height: `${winHeight - 160}px`
        }"
      >
        <ZgFilter type="left" :filters="filters" @ok="toFilter"></ZgFilter>
        <div class="pos-abs wfull left-bottom flx-s fs14">
          <a-switch v-model="fixedLeft" size="small" class="mr5"></a-switch>
          固定视图在左侧
        </div>
      </div>
      <a-card :bordered="false" size="small">
        <div v-if="opt.showPageTitle" slot="title" class="flx-b">
          <div>
            {{ title }}
            <span v-if="!fixedLeft && filter != null">
              <a-divider type="vertical"></a-divider>
              <a-popover v-model="showFilter" placement="bottomLeft" trigger="click">
                <template slot="content">
                  <ZgFilter :filters="filters" @ok="toFilter"></ZgFilter>
                  <div class="flx-a" style="border-top: solid 1px #e6e6e6; margin: 15px -16px 0; padding: 5px 10px 0">
                    <a-switch v-model="fixedLeft" size="small" class="mr5"></a-switch>
                    <span>固定视图在左侧</span>
                  </div>
                </template>
                <template slot="title">
                  <div class="flx-b">
                    <div>选择过滤器</div>
                  </div>
                </template>
                <span @click="showFilter = !showFilter" class="cpt">
                  <span class="mr10">{{ filter.name }}</span>
                  <i class="fa" :class="`fa-caret-${showFilter ? 'up' : 'down'}`" />
                </span>
              </a-popover>
            </span>
          </div>
          <div class="flx-e">
            <a-input
              ref="searchInput"
              v-if="showSearch"
              v-model.trim="searchStr"
              class="w240 mr10"
              :placeholder="placeholder"
              @blur="onSearchInputBlur"
              @keyup.enter.native="search"
            >
              <a-icon slot="prefix" type="search" />
            </a-input>
            <a-tooltip v-else title="搜索" placement="top">
              <div v-if="opt.showSearchBtn" class="btn flx-c" @click="showSearchInput">
                <i class="fa fa-search" />
              </div>
            </a-tooltip>
            <a-tooltip title="刷新" placement="top">
              <div v-if="opt.showRefreshBtn" class="btn flx-c" @click="search">
                <i class="fa fa-refresh" />
              </div>
            </a-tooltip>
            <a-tooltip title="筛选" placement="top">
              <div v-if="opt.showConditionBtn" class="btn flx-c" @click="showCondition = !showCondition">
                <i class="fa" :class="showCondition ? 'fa-compress' : 'fa-filter'" />
              </div>
            </a-tooltip>
            <a-tooltip title="切换视图" placement="top">
              <div v-if="opt.showLayoutMode" class="btn flx-c" @click="listMode = !listMode">
                <i class="fa" :class="listMode ? 'fa-bars' : 'fa-th'" />
              </div>
            </a-tooltip>
            <ZgDropdown v-if="hasBatchBtn" :opts="batchBtns" type="link" class="mr10" @click="toBatch">
              批量操作<i class="fa fa-angle-down ml3" />
            </ZgDropdown>
            <span class="ml10">
              <ZgButton :icon="addBtnIcon || 'plus-circle'" v-if="addBtnName && addBtnName.length > 0" @click="toAdd">
                {{ addBtnName || '新增数据' }}
              </ZgButton>
            </span>
          </div>
        </div>
        <div
          v-show="showCondition && conditions && conditions.length > 0"
          class="wfull mb15 pos-rlt"
          style="background: #f6f7f9; border-radius: 4px"
          :style="{ height: `${conditionHeight}px` }"
        >
          <ZgCondition
            ref="condition"
            :labelCol="labelCol"
            :columnCol="columnCol"
            :showFilterAdminBtn="showFilterAdminBtn"
            :uniqueName="uniqueName"
            :conditions="conditions"
            :showInlineBtn="showInlineBtn"
            :currFilterName="filter && filter.name ? filter.name : ''"
            :extraBtns="extraBtns"
            @extraBtnClick="onExtraBtnClick"
            @search="search"
            @refresh="initFilters"
            @height="(h) => (conditionHeight = h)"
          ></ZgCondition>
        </div>
        <div v-if="opt.showHeaderConfig && listMode" class="wfull pos-rlt">
          <div style="position: absolute; right: 18px; top: 10px; z-index: 999">
            <ZgHeaderConfig
              :uniqueName="uniqueName"
              :headers="headers"
              @change="(t) => $emit('header', t)"
            ></ZgHeaderConfig>
          </div>
        </div>
        <slot name="tabs"> </slot>
        <viewer class="viewer" :images="[]">
          <div :style="{ height: `${winHeight + 40 - extraHeight - (showCondition ? conditionHeight + 15 : 0)}px` }">
            <slot name="thMode" v-if="!listMode" :list="dataList"> </slot>
            <a-table
              v-else
              size="small"
              bordered
              :customHeaderRow="
                () => {
                  return { style: { background: '#f2f2f2' } }
                }
              "
              :pagination="false"
              :row-selection="
                hasBatchBtn || opt.showDataCheck
                  ? {
                    type: this.isRadio ? 'radio' : 'checkbox',
                    selectedRowKeys: ids,
                    onChange: (selectedRowKeys) => (ids = selectedRowKeys),
                    columnWidth: 45
                  }
                  : null
              "
              :data-source="list"
              :scroll="{ x: scrollX, y: winHeight - extraHeight - (showCondition ? conditionHeight + 15 : 0) }"
            >
              <a-table-column :width="45" title="序号">
                <template slot-scope="text, record, index">
                  <div class="wfull tac">{{ index + 1 }}</div>
                </template>
              </a-table-column>
              <slot name="columns"></slot>
              <a-table-column
                v-if="hasDataBtn"
                fixed="right"
                align="center"
                :width="adminWidth === 0 ? 80 : adminWidth"
                title="操作"
              >
                <template slot-scope="text, record">
                  <a-dropdown v-if="adminWidth === 0">
                    <a class="ant-dropdown-link" @click="(e) => e.preventDefault()">
                      <i class="fa fa-ellipsis-h" />
                    </a>
                    <a-menu slot="overlay">
                      <a-menu-item
                        v-show="btn.isShow(record)"
                        v-for="btn in dataBtns"
                        :key="`data-btn-${btn.key}`"
                        @click="onDataBtnClick(btn.key, record)"
                      >
                        <i :class="`fa ${btn.icon} mr5`" />{{ btn.name }}
                      </a-menu-item>
                    </a-menu>
                  </a-dropdown>
                  <div v-else class="flx-s">
                    <a-button
                      class="mr10"
                      :type="btn.type"
                      v-show="btn.isShow(record)"
                      v-for="btn in dataBtns"
                      :key="`data-btn-${btn.key}`"
                      @click="onDataBtnClick(btn.key, record)"
                    >
                      <i :class="`fa ${btn.icon} mr5`" />{{ btn.name }}
                    </a-button>
                  </div>
                </template>
              </a-table-column>
            </a-table>
          </div>
        </viewer>
        <div class="flx-e mt10" v-show="isShowPagination">
          <a-pagination
            showSizeChanger
            showQuickJumper
            v-model="page"
            :total="total"
            :pageSize="pageSize"
            :pageSizeOptions="pageSizeOptions"
            @change="onPageChange"
            @showSizeChange="onPageChange"
            :showTotal="(total) => `总共 ${total} 条记录`"
          />
        </div>
      </a-card>
    </div>
  </div>
</template>
<script>
import { pageMixin } from '@/core/page-mixin'
import ZgFilter from './ZgFilter'
import ZgCondition from './ZgCondition'
import ZgHeaderConfig from './ZgHeaderConfig'
export default {
  components: { ZgFilter, ZgCondition, ZgHeaderConfig },
  mixins: [pageMixin],
  props: {
    pageOpt: {
      type: Object,
      default: () => {
        return {}
      }
    },
    batchBtns: {
      type: Array,
      default: () => {
        return []
      }
    },
    dataBtns: {
      type: Array,
      default: () => {
        return []
      }
    },
    extraBtns: {
      type: Array,
      default: () => {
        return []
      }
    },
    timeout: {
      type: Number,
      default: 5000
    },
    uniqueName: {
      type: String,
      default: ''
    },
    headers: {
      type: Array,
      default: () => {
        return []
      }
    },
    conditions: {
      type: Array,
      default: () => {
        return []
      }
    },
    labelCol: {
      type: Number,
      default: 6
    },
    columnCol: {
      type: Number,
      default: 6
    },
    showFilterAdminBtn: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: '页面标题'
    },
    placeholder: {
      type: String,
      default: '输入关键字，按回车键进行搜索'
    },
    addBtnName: {
      type: String,
      default: null
    },
    addBtnIcon: {
      type: String,
      default: null
    },
    openCondition: {
      type: Boolean,
      default: true
    },
    showInlineBtn: {
      type: Boolean,
      default: true
    },
    extraHeight: {
      type: Number,
      default: 240
    },
    adminWidth: {
      type: Number,
      default: 0
    },
    scrollX: {
      type: Number,
      default: 0
    },
    pageSizeOptions: {
      type: Array,
      default: () => {
        return ['10', '20', '30', '40', '50', '100']
      }
    },
    isShowPagination: {
      type: Boolean,
      default: true
    },
    isRadio: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    hasBatchBtn() {
      return this.batchBtns && this.batchBtns.length > 0
    },
    hasDataBtn() {
      return this.dataBtns && this.dataBtns.length > 0
    },
    opt() {
      return Object.assign(
        {
          // 查询功能
          showSearchBtn: false,
          // 刷新功能
          showRefreshBtn: false,
          // 筛选功能
          showConditionBtn: false,
          // 表头设置功能
          showHeaderConfig: false,
          // 布局模式设置功能
          showLayoutMode: false,
          // 显示数据选择
          showDataCheck: false,
          // 显示页面标题区域
          showPageTitle: true
        },
        this.pageOpt
      )
    },
    dataList() {
      return this.list
    }
  },
  data() {
    return {
      fixedLeft: false,
      fixedLeftWidth: 240,
      loading: false,
      showSearch: false,
      showCondition: this.openCondition,
      conditionHeight: 70,
      showFilter: false,
      obj: null,
      filter: null,
      filters: []
    }
  },
  watch: {
    fixedLeft(v) {
      if (v) {
        this.showFilter = false
      }
    }
  },
  mounted() {
    this.search()
    this.initFilters(true)
  },
  methods: {
    initFilters(changeFilter) {
      // 获取过滤器
      const key = this.currentUser.username + '_diyFilter_' + this.uniqueName
      const result = localStorage.getItem(key)
      if (result) {
        this.filters = JSON.parse(result)
        if (changeFilter) {
          this.filter = this.filters[0]
          this.$refs.condition.set(this.filter.condition)
        }
      } else {
        this.filters = []
        if (changeFilter) {
          this.filter = null
          this.$refs.condition.reset()
        }
      }
    },
    showSearchInput() {
      this.showSearch = true
      setTimeout(() => {
        this.$refs.searchInput.focus()
      })
    },
    onSearchInputBlur() {
      this.showSearch = false
      this.searchStr = ''
    },
    getPageParam() {
      return {
        searchStr: this.searchStr,
        page: this.page,
        pageSize: this.pageSize
      }
    },
    search() {
      this.loading = true
      setTimeout(() => {
        this.loading = false
      }, this.timeout)
      const condition = JSON.parse(this.$refs.condition.getCondition())
      this.$emit(
        'search',
        Object.assign(condition, {
          searchStr: this.searchStr,
          page: this.page,
          pageSize: this.pageSize
        })
      )
    },
    endSearch(opt) {
      this.total = opt.total
      this.list = opt.list
      this.loading = false
    },
    toAdd() {
      this.$emit('add')
    },
    toBatch(opt) {
      this.$emit('batch', opt)
    },
    toFilter(json) {
      this.showFilter = false
      this.filter = json
      this.$refs.condition.set(this.filter.condition)
    },
    onDataBtnClick(key, obj) {
      this.$emit('admin', { key: key, obj: JSON.parse(JSON.stringify(obj)) })
    },
    onExtraBtnClick(key) {
      this.$emit('extra', { key: key })
    },
    onPageChange(page, pageSize) {
      this.page = page
      this.pageSize = pageSize
      this.search()
    },
    setPageIds(ids) {
      this.ids = ids
    }
  }
}
</script>
<style lang="scss">
.ant-table > .ant-table-content .ant-table-header {
  background: #f2f2f2;
}
</style>
<style lang="scss" scoped>
.btn {
  width: 32px;
  height: 32px;
  color: #999;
  &:hover {
    cursor: pointer;
    color: #2979ff;
  }
}
.left-bottom {
  padding: 10px;
  box-sizing: border-box;
  border-top: solid 1px #e6e6e6;
  bottom: 0;
  left: 0;
}
</style>
